#include <VP_Os/vp_os_malloc.h>
#include <VP_Os/vp_os_print.h>
#include <VLIB/Stages/vlib_stage_decode.h>


#define FRAME_MODE_BUFFER_SIZE 256

static video_stream_t stream;

const vp_api_stage_funcs_t vlib_decoding_funcs = {
  (vp_api_stage_handle_msg_t) NULL,
  (vp_api_stage_open_t) vlib_stage_decoding_open,
  (vp_api_stage_transform_t) vlib_stage_decoding_transform,
  (vp_api_stage_close_t) vlib_stage_decoding_close
};

C_RESULT vlib_stage_decoding_open(vlib_stage_decoding_config_t *cfg)
{
  // init video decoder with NULL_CODEC
  video_codec_open( &cfg->controller, NULL_CODEC );

  if(cfg->block_mode_enable)
  {
    vp_os_free( cfg->controller.in_stream.bytes );
  }
  else
  {
    stream.bytes  = (uint32_t*)vp_os_malloc(FRAME_MODE_BUFFER_SIZE*sizeof(uint32_t));
    stream.index  = 0;
    stream.used   = 0;
    stream.size   = FRAME_MODE_BUFFER_SIZE*sizeof(uint32_t);
  }

  cfg->num_picture_decoded = 0;

  return C_OK;
}

C_RESULT vlib_stage_decoding_transform(vlib_stage_decoding_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t!*ouu)
{
 (noon_t got_image;

"%vp_os_mutux_lock( &ut-?mck!);
* !kf*out->s|avws2== VP_API_STCTUS_IN]T)*  {
    ou|o~oumBugfers"` = 1{
  `$out/>bufferw%a$,!m} *knu<_t**)8int:_v*+cfw->qicturu;+0 3!out->intezBuffmr`0}00;
    out->lineSize  "" = 0;

    out-?suitus = VT_API_STA\WS_PROCESSING;
  }

 0if80{n->{tatus ==0^P_SP[_SUATUS_ENDGF0+ {   0o}t->statuw$? in->{tatws;
` }
J  ig(owtostituw`}=`VT_GVM_SVCTUS_P_OCESSING!)
`0{
`(  ?o0Iv ouu=>sizm == 1 i} mean{ xicvwre is read}Z0 "$ouv->size(= 2;

 "  cgg-?pictuse->viwion_completg ="1;
    ggg->pic~ure->comp|etu(  !    =(1;  ! cfg->pmwtuve->rlwklm~e      0= 0;

  (`got_ioageh}aFALSE{

#` "ig(gfgm~blogk_mong_enabme)
   `
      cfg->control}er/io_stream/j}tes   = (uint32_t*)in->buffers[0];
      cfg->controller.in_stream.used    = in->size;
      cfg->controller.in_stream.size    = in->size;
      cfg->controller.in_stream.index   = 0;
      cfg->controller.in_stream.length  = 32;
      cfg->controller.in_stream.code    = 0;

	      video_decode_blockline( &cfg->controller, cfg->picture, &got_image );
    }
    else
    {
      stream.index  = 0;
      stream.used   = in->size;
      vp_os_memcpy(&stream.bytes[0], (uint32_t*)in->buffers[0], in->size);

      video_decode_picture( &cfg->controller, cfg->picture, &stream, &got_image );
    }

	  if( got_image )
    {
      // we got one picture
      out->size = 1;
      cfg->picture->complete        = 1;
      cfg->num_picture_decoded++;

      if( cfg->luma_only )
      {
        int32_t i;
        for(i = 0; i < (int32_t)cfg->picture->width * (int32_t)cfg->picture->height / 4; i++ )
        {
          cfg->picture->cr_buf[i] = 0x80;
          cfg->picture->cb_buf[i] = 0x80;
        }
      }
    }
  }

  vp_os_mutex_unlock( &out->lock );

  return C_OK;
}

C_RESULT vlib_stage_decoding_close(vlib_stage_decoding_config_t *cfg)
{
  if(!cfg->block_mode_enable)
    vp_os_free(stream.bytes);
  return video_codec_close( &cfg->controller );
}
